package com.base.component.ai.agent.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Alfred
 * @version V1.0
 * @since 2024/4/28 17:32
 **/
public class PromptCharacterUtil {
    private static final Pattern CH_QUOTED_TEXT_PATTERN = Pattern.compile("(“.*”)");
    private static final Pattern EN_QUOTED_TEXT_PATTERN = Pattern.compile("(\".*\")");

    /**
     * 将内容中中英文双引号及其中的内容使用特殊字符替换
     * 例如：好的，西湖区有一家叫“海底捞”的火锅店，味道非常不错，推荐你去试试。我也很想和你一起去，不过我今天有事。
     * 更新后的内容：好的，西湖区有一家叫@@@quot#0@@@的火锅店，味道非常不错，推荐你去试试。我也很想和你一起去，不过我今天有事。
     * @param content 内容
     * @return 返回替换map即替换后的内容
     */
    private static QuotedTextReplaceRes replaceQuotationContent(String content) {
        Map<String, String> xyi = new HashMap<>(8);
        AtomicInteger idx = new AtomicInteger(0);
        QuotedTextReplaceRes res = new QuotedTextReplaceRes();
        res.content = content;
        String src = content;
        //中文双引号
        Matcher matcher = CH_QUOTED_TEXT_PATTERN.matcher(src);
        if(matcher.find()) {
            for(int i = 0; i < matcher.groupCount(); i++) {
                int index = idx.getAndIncrement();
                String key = "@@@quot#" + index + "@@@";
                src = src.replace(matcher.group(i), key);
                xyi.put(key, matcher.group(i));
            }
        }

        //英文双引号
        Matcher enMatcher = EN_QUOTED_TEXT_PATTERN.matcher(src);
        if(enMatcher.find()) {
            for(int i = 0; i < enMatcher.groupCount(); i++) {
                int index = idx.getAndIncrement();
                String key = "@@@quot#" + index + "@@@";
                src = src.replace(enMatcher.group(i), key);
                xyi.put(key, enMatcher.group(i));
            }
        }
        res.keyRepMap = xyi;
        res.resContent = src;
        return res;
    }

    /**
     * 从a中提取b中的最长匹配子串，必须符合b的最左匹配规则
     * @param a 内容
     * @param b 搜索串
     * @return 最长匹配子串
     */
    public static String findLongestCommonSubstring(String a, String b) {
        String maxSub = "";
        for(int i = 1; i <= b.length(); i++) {
            String sub = b.substring(0, i);
            if(a.contains(sub) && sub.length() > maxSub.length()) {
                maxSub = sub;
            }
        }
        return maxSub;
    }

    /**
     * 断句，从内容中使用中英文句号，省略号，感叹号，问号断句分割，返回从内容得到完整句子
     * 注意：如果末尾没有约定的分割符，则末尾部分的句子不会返回
     * @param content 内容
     * @return 从内容中提取的完整分句
     */
    public static List<String> punctuation(String content) {
        QuotedTextReplaceRes quotedTextReplaceRes = replaceQuotationContent(content);
        String tmpContent = quotedTextReplaceRes.resContent;

        String cur = "";
        List<String> lis = new ArrayList<>();
        for(int i = 0; i < tmpContent.length(); i++) {
            char chi = tmpContent.charAt(i);
            //先将当前字符追加到末尾
            cur = cur + chi;
            if(chi == '。' || chi == '.' || chi == '！' || chi == '？' || chi == '!' || chi == '?'
                    || chi == '”' || chi == '"') {
                //判断当前字符串末尾是否是符号，如果是符号，则先不处理。
            }else {
                if(cur.length() == 1) {
                    continue;
                }
                char last2ch = cur.charAt(cur.length() - 2);
                if(last2ch == ',' || last2ch == '，') {
                    //                        如果不是符号，则再判断倒数第二个字符是否是中英文逗号或者是换行符，如果是则不处理
                }else if(last2ch == '。' || last2ch == '.' || last2ch == '！' || last2ch == '？' || last2ch == '!' || last2ch == '?'
                        || last2ch == '”') {
                    if(cur.length() >= 3) {
                        char last3ch = cur.charAt(cur.length() - 3);
                        if (last2ch == '.' && last3ch >= 48 && last3ch <= 57) {
                            //如果倒数第二个是点号，而点号前面的字符是数字的化，则先不拆句
                            continue;
                        }
                    }
                    //                                   倒数第二哥字符不符合以上条件，则将末尾字符前的所有内容当成整句
                    lis.add(cur.substring(0, cur.length() - 1));
                    cur = cur.substring(cur.length() -1);
                }
            }
        }

        List<String> finalLis = new ArrayList<>();
        //对分句中的内容做双引号内容恢复
        for(String a : lis) {
            String fina = a;
            for(Map.Entry<String, String> me : quotedTextReplaceRes.keyRepMap.entrySet()) {
                fina = fina.replace(me.getKey(), me.getValue());
            }
            finalLis.add(fina);
        }
        return finalLis;
    }

    /**
     * 并不完善，例如  小明说："你在哪里啊？"   冒号和问号会拆分两个句子中
     * 断句，从内容中使用中英文句号，省略号，感叹号，问号，逗号，分号断句分割，返回从内容得到完整句子
     * 注意：如果末尾没有约定的分割符，则末尾部分的句子不会返回
     * @param content
     * @return
     */
    public static List<String> punctuation2(String content) {
        String cur = "";
        boolean latestIsStop = false;
        List<String> lis = new ArrayList<>();
        for(int i = 0; i < content.length(); i++) {
            char chi = content.charAt(i);
            if(chi == '。') {
                //句号和点号同时也是省略号的一部分
                latestIsStop = true;
                cur = cur + chi;
            }else if(chi == '！' || chi == '？' || chi == '!' || chi == '?' || chi == ',' || chi == '，' || chi == ';' || chi == '；') {
                cur = cur + chi;
                lis.add(cur);
                latestIsStop = false;
                cur = "";
            }else {
                if(latestIsStop) {
                    //如果前面是停止符，当前并不是符号，则前面的内容是完整的句子
                    lis.add(cur);
                    latestIsStop = false;
                    cur = "" + chi;
                }else {
                    latestIsStop = false;
                    cur = cur + chi;
                }
            }
        }
        return lis;
    }

    /**
     * 断句，从内容中使用中英文句号，省略号，感叹号，问号断句分割，返回从内容得到完整句子
     * 注意：如果末尾没有约定的分割符，也会将末尾部分的句子返回
     * @param content
     * @return
     */
    public static List<String> punctuation3(String content) {
        List<String> lis = punctuation(content);
        StringBuilder sb = new StringBuilder(content);
        for(String s : lis) {
            sb.delete(0, s.length());
        }
        if(!sb.isEmpty()) {
            lis.add(sb.toString());
        }
        return lis;
    }

    /**
     * 断句，从内容中使用中英文句号，省略号，感叹号，问号，逗号，分号断句分割，返回从内容得到完整句子
     * 注意：如果末尾没有约定的分割符，也会将末尾部分的句子返回
     * @param content
     * @return
     */
    public static List<String> punctuation4(String content) {
        List<String> lis = punctuation2(content);
        StringBuilder sb = new StringBuilder(content);
        for(String s : lis) {
            sb.delete(0, s.length());
        }
        if(!sb.isEmpty()) {
            lis.add(sb.toString());
        }
        return lis;
    }

    public static class QuotedTextReplaceRes {
        /**
         * 替换的占位符对应的文案
         */
        private Map<String, String> keyRepMap;
        /**
         * 双引号内容替换后的结果
         */
        private String resContent;
        /**
         * 原始文本内容
         */
        private String content;

        public Map<String, String> getKeyRepMap() {
            return keyRepMap;
        }

        public String getResContent() {
            return resContent;
        }

        public String getContent() {
            return content;
        }
    }
}
